/**
 * 2010(c) Copyright Oceansoft Information System Co.,LTD. All rights reserved.
 * <p>
 * Compile: JDK1.6+
 * <p>
 * ��Ȩ����(C)������ŷ��������޹�˾
 * <p>
 * ��˾��ƣ�����ŷ��������޹�˾
 * <p>
 * ��˾��ַ������������ɽ·1������ʵѵ���
 * <p>
 * ��ַ: http://www.oceansoft.com.cn
 * <p>
 * �汾: Ȩ��������ݹ���ƽ̨_1.0
 * <p>
 * ����: 110510(��ΰ��)
 * <p>
 * <p>
 * �ļ���: ImageUtil.java
 * <p>
 * �����ʱ��:2014-10-4 ����11:51:10
 * <p>
 * ������: 110510(��ΰ��)
 * <p>
 * ������: Ȩ��������ݹ���ƽ̨
 * <p>
 * ���ڲ���: ����һ��-��������
 * <p>
 * email��zhuwj@oceansoft.com.cn
 * <p>
 * <p>
 */

package com.oceansoft.mobile.econsole.modules.api.util;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Transparency;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.swing.ImageIcon;

public final class ImageUtil {
	private ImageUtil() {
	}
	
	
	public static BufferedImage toBufferedImage(Image image) {
        if (image instanceof BufferedImage) {
            return (BufferedImage)image;
         }
     
        // This code ensures that all the pixels in the image are loaded
         image = new ImageIcon(image).getImage();
     
        // Determine if the image has transparent pixels; for this method's
        // implementation, see e661 Determining If an Image Has Transparent Pixels
        //boolean hasAlpha = hasAlpha(image);
     
        // Create a buffered image with a format that's compatible with the screen
         BufferedImage bimage = null;
         GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        try {
            // Determine the type of transparency of the new buffered image
            int transparency = Transparency.OPAQUE;
           /* if (hasAlpha) {
                 transparency = Transparency.BITMASK;
             }*/
     
            // Create the buffered image
             GraphicsDevice gs = ge.getDefaultScreenDevice();
             GraphicsConfiguration gc = gs.getDefaultConfiguration();
             bimage = gc.createCompatibleImage(
                 image.getWidth(null), image.getHeight(null), transparency);
         } catch (HeadlessException e) {
            // The system does not have a screen
         }
     
        if (bimage == null) {
            // Create a buffered image using the default color model
            int type = BufferedImage.TYPE_INT_RGB;
            //int type = BufferedImage.TYPE_3BYTE_BGR;//by wang
            /*if (hasAlpha) {
                 type = BufferedImage.TYPE_INT_ARGB;
             }*/
             bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);
         }
     
        // Copy image to buffered image
         Graphics g = bimage.createGraphics();
     
        // Paint the image onto the buffered image
         g.drawImage(image, 0, 0, null);
         g.dispose();
     
        return bimage;
     }
	

	/** ������ɫ͸����(0~255) **/
	public static final Color newColor(Color c, int alp) {
		return new Color(c.getRed(), c.getGreen(), c.getBlue(), alp);
	}

	/** ����������ͼƬ **/
	public static BufferedImage stretch(BufferedImage src, double rate) {
		if (src == null || rate <= 0)
			return null;
		 FileOutputStream out = null;
		 BufferedImage dest = null;
		 //BufferedImage src = javax.imageio.ImageIO.read(file);  
         int width = (int)(src.getWidth()*rate);  
         int height = (int) (src.getHeight()*rate);  
         // ��С�߳� 
         BufferedImage tag = new BufferedImage(width , height , BufferedImage.TYPE_INT_RGB);  
         // ���� ��С  ���ͼƬ 
         tag.getGraphics().drawImage(src, 0, 0, width , height , null);  
         
         /*try{
         out = new FileOutputStream("h:\\a.jpg");  
         JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);  
         encoder.encode(tag);  
         dest = ImageIO.read(new File("h:\\a.jpg"));
         }catch (Exception e) {
			e.printStackTrace();
		}*/
         return tag;
         
        /* 
		
		int w = img.getWidth(null);
		int h = img.getHeight(null);
		int width = (int) (w * rate);
		int height = (int) (h * rate);
		BufferedImage rImg = getSpaceImage(width, height, null);
		rImg.getGraphics()
				.drawImage(img, 0, 0, width, height, 0, 0, w, h, null);
		return rImg;*/
	}

	public static final void revolve(Graphics g, Image img, int x, int y,
			int rx, int ry, int ratio) {
		Graphics2D g2d = (Graphics2D) g.create();
		g2d.translate(x + rx, y + ry);
		g2d.rotate(Math.toRadians(ratio));
		g2d.drawImage(img, -rx, -ry, null);
	}

	/**
	 * ͸��һ�η�Χ
	 * 
	 * @param img
	 * @param left
	 * @param top
	 * @param right
	 * @param bottom
	 * @param alp
	 */
	public static final void alphaImage(BufferedImage img, int left, int top,
			int right, int bottom, int alp) {
		alp = alp < 0 ? 0 : alp > 255 ? 255 : alp;
		for (int ti = left; ti < right; ti++) {
			for (int tj = top; tj < bottom; tj++) {
				Color c = new Color(img.getRGB(ti, tj));
				img.setRGB(ti, tj,
						new Color(c.getRed(), c.getGreen(), c.getBlue(), alp)
								.getRGB());
			}
		}
	}

	/**
	 * ��¡һֱͼƬ
	 * 
	 * @param img
	 * @return
	 */
	public static BufferedImage cloneImage(Image img) {
		BufferedImage rImg = null;
		if (img != null) {
			rImg = getSpaceImage(img.getWidth(null), img.getHeight(null), null);
			rImg.getGraphics().drawImage(img, 0, 0, null);
		}
		return rImg;
	}

	/**
	 * ͸��ͼƬ
	 * 
	 * @param img
	 * @param alp
	 */
	public static final void alphaImage(BufferedImage img, int alp) {
		alphaImage(img, 0, 0, img.getWidth(), img.getHeight(), alp);
	}

	public static BufferedImage getSpaceImage(int width, int height, Color color) {
		BufferedImage img = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_ARGB_PRE);
		if (color != null) {
			Graphics g = img.getGraphics();
			g.setColor(color);
			g.fillRect(0, 0, width, height);
		} else {
			alphaImage(img, 0);
		}
		return img;
	}

	/**
	 * ��תһ���Ƕ�
	 * 
	 * @param image
	 * @param degree
	 * @param bgcolor
	 * @return
	 * @throws IOException
	 */
	public static BufferedImage rotateImage(BufferedImage image, int degree,
			Color bgcolor) throws IOException {

		int iw = image.getWidth();// ԭʼͼ��Ŀ��
		int ih = image.getHeight();// ԭʼͼ��ĸ߶�
		int w = 0;
		int h = 0;
		int x = 0;
		int y = 0;
		degree = degree % 360;
		if (degree < 0)
			degree = 360 + degree;// ���Ƕ�ת����0-360��֮��
		double ang = Math.toRadians(degree);// ���Ƕ�תΪ����

		/**
		 * ȷ����ת���ͼ��ĸ߶ȺͿ��
		 */

		if (degree == 180 || degree == 0 || degree == 360) {
			w = iw;
			h = ih;
		} else if (degree == 90 || degree == 270) {
			w = ih;
			h = iw;
		} else {
			int d = iw + ih;
			w = (int) (d * Math.abs(Math.cos(ang)));
			h = (int) (d * Math.abs(Math.sin(ang)));
			// w = (int) (sinVal*ih) + (int) (cosVal*iw);
			// h = (int) (sinVal*iw) + (int) (cosVal*ih);
		}

		x = (w / 2) - (iw / 2);// ȷ��ԭ�����
		y = (h / 2) - (ih / 2);
		BufferedImage rotatedImage = new BufferedImage(w, h, image.getType());
		Graphics2D gs = (Graphics2D) rotatedImage.getGraphics();
		if (bgcolor == null) {
			rotatedImage = gs.getDeviceConfiguration().createCompatibleImage(w,
					h, Transparency.TRANSLUCENT);
		} else {
			gs.setColor(bgcolor);
			gs.fillRect(0, 0, w, h);// �Ը���ɫ������ת��ͼƬ�ı���
		}

		AffineTransform at = new AffineTransform();
		at.rotate(ang, w / 2, h / 2);// ��תͼ��
		at.translate(x, y);
		AffineTransformOp op = new AffineTransformOp(at,
				AffineTransformOp.TYPE_BICUBIC);
		op.filter(image, rotatedImage);
		image = rotatedImage;
		return image;
		/*
		 * ByteArrayOutputStream byteOut= new ByteArrayOutputStream();
		 * ImageOutputStream iamgeOut =
		 * ImageIO.createImageOutputStream(byteOut);
		 * 
		 * // ImageIO.write(image, "png", iamgeOut); ImageIO.write(image, "png",
		 * new File("h:\\zwj_2.png")); InputStream inputStream = new
		 * ByteArrayInputStream(byteOut.toByteArray());
		 * 
		 * return inputStream;
		 */
	}

	private static Rectangle CalcRotatedSize(Rectangle src, int angel) {
		// if angel is greater than 90 degree, we need to do some conversion
		if (angel >= 90) {
			if (angel / 90 % 2 == 1) {
				int temp = src.height;
				src.height = src.width;
				src.width = temp;
			}
			angel = angel % 90;
		}

		double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2;
		double len = 2 * Math.sin(Math.toRadians(angel) / 2) * r;
		double angel_alpha = (Math.PI - Math.toRadians(angel)) / 2;
		double angel_dalta_width = Math.atan((double) src.height / src.width);
		double angel_dalta_height = Math.atan((double) src.width / src.height);

		int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha
				- angel_dalta_width));
		int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha
				- angel_dalta_height));
		int des_width = src.width + len_dalta_width * 2;
		int des_height = src.height + len_dalta_height * 2;
		return new java.awt.Rectangle(new Dimension(des_width, des_height));
	}

	public static BufferedImage Rotate(Image src, int angel, Color bgcolor) {
		int src_width = src.getWidth(null);
		int src_height = src.getHeight(null);
		// calculate the new image size
		Rectangle rect_des = CalcRotatedSize(new Rectangle(new Dimension(
				src_width, src_height)), angel);

		BufferedImage res = null;
		res = new BufferedImage(rect_des.width, rect_des.height,
				BufferedImage.TYPE_INT_RGB);
		Graphics2D g2 = res.createGraphics();
		// transform
		g2.translate((rect_des.width - src_width) / 2,
				(rect_des.height - src_height) / 2);
		g2.rotate(Math.toRadians(angel), src_width / 2, src_height / 2);

		if (bgcolor == null) {
			g2.getDeviceConfiguration().createCompatibleImage(rect_des.width,
					rect_des.height, Transparency.TRANSLUCENT);
		} else {
			g2.setColor(bgcolor);
			g2.fillRect(0, 0, rect_des.width, rect_des.height);// �Ը���ɫ������ת��ͼƬ�ı���
		}

		g2.drawImage(src, null, null);
		return res;
	}

	public static BufferedImage Rotate(Image src, int angel, double size,
			Color bgcolor) {
		int src_width = (int) (src.getWidth(null) * size);
		int src_height = (int) (src.getHeight(null) * size);
		// calculate the new image size
		Rectangle rect_des = CalcRotatedSize(new Rectangle(new Dimension(
				src_width, src_height)), angel);

		BufferedImage res = null;
		res = new BufferedImage(rect_des.width, rect_des.height,
				BufferedImage.TYPE_INT_RGB);
		Graphics2D g2 = res.createGraphics();
		// transform
		g2.translate((rect_des.width - src_width) / 2,
				(rect_des.height - src_height) / 2);
		g2.rotate(Math.toRadians(angel), src_width / 2, src_height / 2);

		if (bgcolor == null) {
			g2.getDeviceConfiguration().createCompatibleImage(rect_des.width,
					rect_des.height, Transparency.TRANSLUCENT);
		} else {
			g2.setColor(bgcolor);
			g2.fillRect(0, 0, rect_des.width, rect_des.height);// �Ը���ɫ������ת��ͼƬ�ı���
		}
		g2.setBackground(new Color(255, 255, 255));
		g2.drawImage(src, null, null);
		return res;
	}

	// w/15*4 = rang
	public static BufferedImage bycImage(BufferedImage bufIBody, int fixw,
			int fixh, double rang) {

		int w = bufIBody.getWidth();
		int h = bufIBody.getHeight();

		int alpha = 0; // alphaȡֵ0-100,0��ʾ��ȫ͸��
		int rgb;
		// i��ʾBufferedImage��x��꣬j��ʾBufferedImage��y���
		for (int i = bufIBody.getMinX(); i < bufIBody.getWidth(); i++) {

			for (int j = bufIBody.getMinY(); j < bufIBody.getHeight(); j++) {
				rgb = bufIBody.getRGB(i, j);
				// isRang(int curr_w,int curr_h,int w,int h,int fixw,int
				// fixh,int qo)
				if (isRang(i, j, w, h, fixw, fixh, 0, rang)
						|| isRang(i, j, w, h, fixw, fixh, 1, rang)) { // ָ������͸����
					rgb = ((alpha) << 24) | (rgb & 0x00ffffff); // ��ʽ��λ����
					rgb = new Color(255, 255, 255).getRGB();
				}
				bufIBody.setRGB(i, j, rgb);
				// Ҳ����ȡ��ֵ����R,G,B��ֵ����ɫ���д���
				// int R =rgb & 0xff0000 >>> 16;
				// int G= rgb & 0xff00 >>> 8;
				// int B= rgb & 0xff;
				// if(B < 200){
				// B += (10*(k+1));
				// }

				// System.out.println(k+"  j=  "+j+"   "+ R + ":" + G + ":" +
				// B);
				// rgb = new Color(0, 0,0).getRGB();
				// rgb = ((alpha + 1) << 24) | (rgb & 0x00ffffff);
				// bufIBody.setRGB(i, j, rgb);

			}
		}
		return bufIBody;
	}

	/**
	 * �����Ҷ��
	 * 
	 * @param curr_w
	 * @param curr_h
	 * @param w
	 * @param h
	 * @param fixw
	 * @param fixh
	 * @param qo
	 *            ����ż��
	 * @param rang����Χ
	 * @return
	 */
	private static boolean isRang(int curr_w, int curr_h, int w, int h,
			int fixw, int fixh, int qo, double rang) {
		int w_n = w / fixw;
		int h_n = h / fixh;

		boolean bw = false;
		boolean bh = false;
		for (int i = 0 + qo; i < w_n; i += 2) {
			if (curr_w >= i * fixw && curr_w <= (i + 1) * fixw && curr_w < rang) {
				bw = true;
				break;
			}
		}

		for (int i = 0 + qo; i < h_n; i += 2) {
			if (curr_h >= i * fixh && curr_h <= (i + 1) * fixh) {
				bh = true;
				break;
			}
		}
		return bw && bh;
	}

	/*
	 * ��ݳߴ�ͼƬ���вü�
	 */
	public static BufferedImage cutCenterImage(String src, int w, int h)
			throws IOException {
		Iterator iterator = ImageIO.getImageReadersByFormatName("jpg");
		ImageReader reader = (ImageReader) iterator.next();
		InputStream in = new FileInputStream(src);
		ImageInputStream iis = ImageIO.createImageInputStream(in);
		reader.setInput(iis, true);
		ImageReadParam param = reader.getDefaultReadParam();
		int imageIndex = 0;
		Rectangle rect = new Rectangle((reader.getWidth(imageIndex) - w) / 2,
				(reader.getHeight(imageIndex) - h) / 2, w, h);
		param.setSourceRegion(rect);
		BufferedImage bi = reader.read(0, param);
		return bi;
		// ImageIO.write(bi, "jpg", new File(dest));
	}

	public static BufferedImage cutCenterImage(String src, int fix)
			throws IOException {
		// int w,int h;
		Iterator iterator = ImageIO.getImageReadersByFormatName("jpg");
		ImageReader reader = (ImageReader) iterator.next();
		InputStream in = new FileInputStream(src);
		ImageInputStream iis = ImageIO.createImageInputStream(in);
		reader.setInput(iis, true);
		ImageReadParam param = reader.getDefaultReadParam();
		int imageIndex = 0;
		// ���ͼƬԭʼ��С �������Ŵ�С
		int w = reader.getWidth(imageIndex) - fix*reader.getWidth(imageIndex)/100;
		int h = reader.getHeight(imageIndex) - fix*reader.getHeight(imageIndex)/100;
		//System.out.println(w);
		Rectangle rect = new Rectangle((reader.getWidth(imageIndex) - w) / 2,
				(reader.getHeight(imageIndex) - h) / 2, w, h);
		param.setSourceRegion(rect);
		BufferedImage bi = reader.read(0, param);
		return bi;
		// ImageIO.write(bi, "jpg", new File(dest));
	}

	// direct 0 left2right 1 up2topdown 2 right2left 3down2up
	// range ������ʼλ��
	public static BufferedImage cutDirectionImage(String src, double fix,
			int direct, int range) throws IOException {
		// int w,int h;
		Iterator iterator = ImageIO.getImageReadersByFormatName("jpg");
		ImageReader reader = (ImageReader) iterator.next();
		InputStream in = new FileInputStream(src);
		ImageInputStream iis = ImageIO.createImageInputStream(in);
		reader.setInput(iis, true);
		ImageReadParam param = reader.getDefaultReadParam();

		int imageIndex = 0;
		// ���ͼƬԭʼ��С �������Ŵ�С
		int w = (int)(reader.getWidth(imageIndex) * fix);
		int h = (int)(reader.getHeight(imageIndex) * fix);

		int x = 0, y = 0;
		if (direct == 0) {
			x = range;
			y = 0;
			
			if(x>=reader.getWidth(imageIndex)-w)
			{
				x = reader.getWidth(imageIndex)-w;
			}
			
		}
		else if(direct==1){
			x = reader.getWidth(imageIndex)-w;
			y = range;
			if(y>=reader.getHeight(imageIndex)-h)
			{
				y = reader.getWidth(imageIndex)-h;
			}
		}
		else if(direct==2){
			x = reader.getWidth(imageIndex)-w - range;
			y = reader.getWidth(imageIndex)-h;
			if(x<=0)
			{
				x = 0;
			}
		}
		else if(direct==3){
			x = 0;
			y = reader.getWidth(imageIndex)-h - range;
			if(y<=0)
			{
				x = 0;
			}
		}
		else
		{
			return cutCenterImage(src,range);
		}

		Rectangle rect = new Rectangle(x, y, w, h);
		param.setSourceRegion(rect);
		BufferedImage bi = reader.read(0, param);
		return bi;
		// ImageIO.write(bi, "jpg", new File(dest));
	}

	/*
	 * ͼƬ�ü�����֮һ
	 */
	public static void cutHalfImage(String src, String dest) throws IOException {
		Iterator iterator = ImageIO.getImageReadersByFormatName("jpg");
		ImageReader reader = (ImageReader) iterator.next();
		InputStream in = new FileInputStream(src);
		ImageInputStream iis = ImageIO.createImageInputStream(in);
		reader.setInput(iis, true);
		ImageReadParam param = reader.getDefaultReadParam();
		int imageIndex = 0;
		int width = reader.getWidth(imageIndex) / 2;
		int height = reader.getHeight(imageIndex) / 2;
		Rectangle rect = new Rectangle(width / 2, height / 2, width, height);
		param.setSourceRegion(rect);
		BufferedImage bi = reader.read(0, param);
		ImageIO.write(bi, "jpg", new File(dest));
	}

	/*
	 * ͼƬ�ü�ͨ�ýӿ�
	 */

	public static BufferedImage cutImage(String src, int x, int y, int w, int h)
			throws IOException {
		Iterator iterator = ImageIO.getImageReadersByFormatName("jpg");
		ImageReader reader = (ImageReader) iterator.next();
		InputStream in = new FileInputStream(src);
		ImageInputStream iis = ImageIO.createImageInputStream(in);
		reader.setInput(iis, true);
		ImageReadParam param = reader.getDefaultReadParam();
		Rectangle rect = new Rectangle(x, y, w, h);
		param.setSourceRegion(rect);
		BufferedImage bi = reader.read(0, param);
		return bi;
		// ImageIO.write(bi, "jpg", new File(dest));

	}

	/*
	 * ͼƬ����
	 */
	public static void zoomImage(String src, String dest, int w, int h)
			throws Exception {
		double wr = 0, hr = 0;
		File srcFile = new File(src);
		File destFile = new File(dest);
		BufferedImage bufImg = ImageIO.read(srcFile);
		Image Itemp = bufImg.getScaledInstance(w, h, bufImg.SCALE_SMOOTH);
		wr = w * 1.0 / bufImg.getWidth();
		hr = h * 1.0 / bufImg.getHeight();
		AffineTransformOp ato = new AffineTransformOp(
				AffineTransform.getScaleInstance(wr, hr), null);
		Itemp = ato.filter(bufImg, null);
		try {
			ImageIO.write((BufferedImage) Itemp,
					dest.substring(dest.lastIndexOf(".") + 1), destFile);
		} catch (Exception ex) {
			ex.printStackTrace();
		}

	}
	
	
	
	public static BufferedImage zoomImage(BufferedImage src, int w, int h)
			throws Exception {
		double wr = 0, hr = 0;
		Image Itemp = src.getScaledInstance(w, h, src.SCALE_SMOOTH);
		wr = w * 1.0 / src.getWidth();
		hr = h * 1.0 / src.getHeight();
		AffineTransformOp ato = new AffineTransformOp(
				AffineTransform.getScaleInstance(wr, hr), null);
		Itemp = ato.filter(src, null);
		return (BufferedImage)Itemp;

	}
	
	
	

}